#!/bin/sh -ef
#
# Copyright (C) 2003-2019  Dmitry V. Levin <ldv@altlinux.org>
# 
# The install utility for the hasher project
#
# SPDX-License-Identifier: GPL-2.0-or-later
#

. hsh-sh-functions

show_help()
{
	cat <<EOF
hsh-install - install binary packages into chroot prepared by hsh-initroot.

Usage: $PROG [options] [<path-to-workdir>] <package>...

<path-to-workdir> must be valid hasher directory.

Options:
  --excludedocs             do not install documentation files;
  --hasher-priv-dir=DIR     hasher-priv directory;
  --mountpoints=LIST        comma-separated list of known mount points;
  --number=NUMBER           subconfig identifier;
  --wait-lock               wait for workdir and hasher-priv locks;
  --no-wait-lock            do not wait for workdir and hasher-priv locks;
  -q, --quiet               try to be more quiet;
  -v, --verbose             print a message for each action;
  -V, --version             print program version and exit;
  -h, --help                show this text and exit.
    
Report bugs to http://bugs.altlinux.ru/

EOF
	exit
}

TEMP=`getopt -n $PROG -o $getopt_common_opts -l excludedocs,hasher-priv-dir:,no-lock,mountpoints:,number:,save-fakeroot,wait-lock,no-wait-lock,$getopt_common_longopts -- "$@"` ||
	show_usage
eval set -- "$TEMP"

while :; do
	case "$1" in
		--excludedocs) exclude_docs=--excludedocs
			;;
		--hasher-priv-dir)
			hasher_priv_dir="$(opt_check_dir "$1" "$2")"
			shift
			;;
		--mountpoints) shift; known_mountpoints="$1"
			;;
		--no-lock) no_lock=1
			;;
		--number)
			number="$(opt_check_number_ge_0 "$1" "$2")"
			shift
			;;
		--save-fakeroot) message "Warning: obsolete option $1 ignored."
			;;
		--wait-lock) lock_nowait=
			;;
		--no-wait-lock) lock_nowait=1
			;;
		--) shift; break
			;;
		*) parse_common_option "$1"
			;;
	esac
	shift
done

if [ -z "$workdir" ]; then
	# At least two arguments.
	[ "$#" -ge 2 ] || show_usage 'Insufficient arguments.'
else
	# At least one argument.
	[ "$#" -ge 1 ] || show_usage 'Insufficient arguments.'
fi

if [ -z "$workdir" -o -d "${1:-}" ]; then
	set_workdir "${1:-}"
	shift
else
	set_workdir
fi

# At least one argument.
[ "$#" -ge 1 ] || show_usage 'Insufficient arguments.'

lock_workdir
[ -d "$chroot" ] || fatal "$chroot: cannot find chroot."
[ -d "$aptbox" ] || fatal "$aptbox: cannot find aptbox."

filelist="$(print_uris "$@")" ||
	fatal 'Failed to generate package file list.'
if [ -z "$filelist" ]; then
	verbose 'Nothing to install.'
	exit 0
fi

deduce_lock_hasher_priv

copy_chroot_incoming $filelist

check_tty

# Calculate list of packages which should not be installed
for f in $filelist; do
	f="${f##*/}"
	for p in $noinstall_pattern_list; do
		if [ -z "${f##$p}" ]; then
			printf '%s\n' "$f"
			continue 2
		fi
	done
done |sed 's/[][?*\]/\\&/g' >"$chroot"/.in/.rpmi-justdb.list

# Calculate list of packages which should be installed
for f in $filelist; do
	f="${f##*/}"
	for p in $noinstall_pattern_list; do
		if [ -z "${f##$p}" ]; then
			continue 2
		fi
	done
	printf '%s\n' "$f"
done |sed 's/[][?*\]/\\&/g' >"$chroot"/.in/.rpmi-install.list

if [ -n "$known_mountpoints" ]; then
	# Calculate mountpoints from packages being installed.
	create_entry_header
	cat >>"$entry" <<__EOF__
cat .rpmi-justdb.list .rpmi-install.list 2>/dev/null |
	xargs -r rpmquery -pR -- |
	LC_ALL=C grep ^/ |LC_ALL=C tr -d '[[:blank:]]' |sort -u
__EOF__
	file_deps="$(wlimit_time_elapsed=$wlimit_time_short wlimit_time_idle=$wlimit_time_short wlimit_bytes_written=$wlimit_bytes_out \
		    chrootuid2 </dev/null)" &&
		verbose 'fetched file dependencies from packages being installed.' ||
		fatal 'failed to fetch file dependencies from packages being installed.'
	calculate_required_mountpoints "$file_deps"
	calculate_required_mountpoints_from_installed
fi

create_entry_fakeroot_header
cat >>"$entry" <<__EOF__
${exclude_docs:+export RPM_EXCLUDEDOCS=1}
if [ -s .rpmi-justdb.list ]; then
	${rpmi:-$def_rpmi} -i --ignorearch ${exclude_docs:+--excludedocs} --nodeps --ignoresize --justdb .rpmi-justdb.list
fi
if [ -s .rpmi-install.list ]; then
	${rpmi:-$def_rpmi} -i --ignorearch ${exclude_docs:+--excludedocs} .rpmi-install.list
fi
ldconfig
if type adjust_kernel_headers >/dev/null 2>&1; then
	adjust_kernel_headers --first
fi
if [ -x /.host/postin ]; then
	/.host/postin
fi
__EOF__

wlimit_time_elapsed=$wlimit_time_long \
wlimit_time_idle=$wlimit_time_long \
requested_mountpoints="$required_mountpoints" \
    chrootuid1 </dev/null &&
	verbose 'Packages installation complete.' ||
	fatal 'Packages installation failed.'

purge_chroot_in
update_RPM_database $filelist

